//*****************************************************************************
//
// distanceIR_task.c - Control library for the distance IR sensor on the evalbot
// This class forces the analog input to pin PE7 because the pin was isolated.
// from the other open GPIO pins. This way it is easer to add other components
// that require more pins such as the IR line reader.
//*****************************************************************************

#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "utils/scheduler.h"

//
// This array is used for storing the data read from the ADC FIFO. It
// must be as large as the FIFO for the sequencer in use.  This example
// uses sequence 3 which has a FIFO depth of 1.  If another sequence
// was used with a deeper FIFO, then the array size must be changed.
//
static unsigned long ulADC0_Value[1];

//****************************************************************************
//
// This function is the Distance IR "task".  It is called periodically from the
// scheduler in the main application loop.  When this happens it just takes a
// reading from the IR sensor and stores it.
//
//****************************************************************************
void
DistanceIRTask(void *pvParam)
{
    //
    // Trigger the ADC conversion.
    //
    ADCProcessorTrigger(ADC0_BASE, 3);

    //
    // Wait for conversion to be completed.
    //
    while(!ADCIntStatus(ADC0_BASE, 3, false))
    {
    }

    //
    // Read ADC Value.
    //
    ADCSequenceDataGet(ADC0_BASE, 3, ulADC0_Value);
}

//****************************************************************************
//
// This function returns a cleaned version of the distance IR reading
// for now it will just check to see if it is greater then 5 and less then
// 1000. During test it bounces around 7-10 for nothing in front.
// 600 = about 3 inches in front of the evalbot.
//
// This was removed and only outputs the dirty value. It is not handled by the
// auto_task. This was done to improve performance.
//
//****************************************************************************
unsigned long
DistanceIRGet(void){

	return ulADC0_Value[0];
}

//****************************************************************************
//
// This function initializes the Distance IR task. It should be called from the
// application initialization code.
//
//****************************************************************************
void
DistanceIRTaskInit(void *pvParam)
{
    //
    // Enable the ADC0 interface...it matches the E7 pin
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    //
    // Select the analog ADC function for these pins.
    // This is using the GIO pin API for simplicity
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_7);

    //
    // Enable sample sequence 3 with a processor signal trigger. And
    // configure it for step 0 sequence 3. This is selected cause I
    // only need to check it once.
    ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
    ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE |
                             ADC_CTL_END);

    //
    // Since sample sequence 3 is now configured, it must be enabled.
    //
    ADCSequenceEnable(ADC0_BASE, 3);

    //
    // Clear the interrupt status flag.
    //
    ADCIntClear(ADC0_BASE, 3);
}
